# 程序中有错误，即代码编写的过程中编译器一直在检查各个地方是否有错误，通常用红色波浪线标示，这是必须纠正的
# 程序中也有异常，与错误不同，往往不能简单的察觉出来，多是类似于bug的缺陷，一旦触发了，程序的执行将会受阻
# 比如：int 转型是有限制的，超出限制会报错，又如：一般文件的读取操作若对象不存在，程序也报错，但是这些都不是必然发生的
# 为防万一，我们需要对异常进行处理，引入异常捕获
try:  # 缩进内写的代码是有可能出现异常的代码
    num = int(input('请输入一个正整数：'))
    print(f'这就是你刚才输入的：{num}')

except:  # 异常捕获的范围控制，只写个 except 意味着所有类型异常都可捕获，可以选择精确捕获，异常捕获后执行缩进内的代码（块），否则不执行
    print("你是脑残吗？！看不懂字吗？！叫你输入的是'正整数'！！！")
print('我是后面的代码，看见我被输出了那就意味着异常被成功捕获（如果有的话）。')  # 如果前面使用了足够范围的异常捕获，那么不论是否存在异常，这条及之后的代码都会执行下去
try:
    num = int(input('请输入一个正整数：'))
    print(f'这就是你刚才输入的：{num}')
    print(10 / num)  # 这句语句的作用在于开放其它异常的可能，比如输入0将会有异常：ZeroDivisionError

except ValueError:  # 异常捕获的范围控制是数据异常，这是种精确捕获，异常捕获后执行缩进内的代码（块），否则不执行，显然这次的不执行有没捕获成功异常的可能
    print("你是脑残吗？！看不懂字吗？！叫你输入的是'正整数'！！！")
# except ZeroDivisionError:  # 异常捕获的范围控制是零除异常，这是种精确捕获，异常捕获后执行缩进内的代码（块），否则不执行，显然加上这个捕获器捕获范围更大了
#     print("看见你输入的是个除数了吗？再输0试试？！！！")
print('我是后面的代码，看见我被输出了那就意味着异常被成功捕获（如果有的话）。')  # 显然，若前面使用的捕获器范围小了，那就可能没能成功捕获异常，也因此这行代码可能轮不到执行
# 常用的异常处理格式：
try:
    num = int(input('请输入一个正整数：'))
    print(f'这就是你刚才输入的：{num}')
    print(10 / num)

except Exception as e:  # Exception 是一个常见异常归纳出来的父类，基本上有了它就省事了，可以不用分开写各类异常捕获器，同时可把捕获到的异常信息传给对象 e
    print(f'程序运行时发生异常：{e}')
else:  # else 可以用于异常处理，它的缩进下的代码是在没有异常的情况下执行，当然也可能是因为异常没捕获到所以没执行
    print('很好，程序运行未见异常。')
print('我是后面的代码，看见我被输出了那就意味着异常被成功捕获（如果有的话）。')  # 实际上，像这种在异常处理代码外顶格写的内容基本上都是不论是否有异常都会执行，前提是
# 有异常需要被成功捕获，再一个就是，这样写的效果等价于上行再加个 finally: ，效果一样的
